package com.zmzncs.lmtc.common.util;

import com.alibaba.fastjson.JSONObject;
import com.zmzncs.lmtc.common.pojo.daoer.MonthlyCarInfoRes;
import com.zmzncs.lmtc.common.pojo.mpMessage.InParkMessage;
import com.zmzncs.lmtc.common.pojo.mpMessage.OpenServiceMessage;
import com.zmzncs.lmtc.common.pojo.mpMessage.OutParkMessage;
import com.zmzncs.lmtc.common.pojo.mpMessage.RechargeSuccess;
import com.zmzncs.lmtc.module.customer.dao.CarDao;
import com.zmzncs.lmtc.module.customer.dao.CardDao;
import com.zmzncs.lmtc.module.customer.dao.CustomerDao;
import com.zmzncs.lmtc.module.customer.pojo.car.CarDTO;
import com.zmzncs.lmtc.module.customer.pojo.card.CardDTO;
import com.zmzncs.lmtc.module.customer.pojo.customer.CustomerDTO;
import com.zmzncs.lmtc.module.order.dao.OrderInfoDao;
import com.zmzncs.lmtc.module.order.dao.OrderTradeRecordDao;
import com.zmzncs.lmtc.module.order.pojo.order_info.OrderInfoDTO;
import com.zmzncs.lmtc.module.order.pojo.order_trade_record.OrderTradeRecordDTO;
import com.zmzncs.lmtc.module.park.dao.ParkInfoDao;
import com.zmzncs.lmtc.module.park.pojo.parkinfo.ParkInfo;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * @Author 高博文
 * @Date 2020/10/26 10:41
 */
@Slf4j
@Component
public class MpMessageUtil {

    //入场通知
    private String inPark;
    @Value("${mp.message-url.inPark}")
    public void setInPark(String inPark) {
        this.inPark = inPark;
    }

    //离场通知
    private String outPark;
    @Value("${mp.message-url.outPark}")
    public void setOutPark(String outPark) {
        this.outPark = outPark;
    }

    //服务开通
    private String openService;
    @Value("${mp.message-url.openService}")
    public void setOpenService(String openService) {
        this.openService = openService;
    }

    //充值成功通知
    private String rechargeSuccess;
    @Value("${mp.message-url.rechargeSuccess}")
    public void setRechargeSuccess(String rechargeSuccess) {
        this.rechargeSuccess = rechargeSuccess;
    }

    @Autowired
    CardDao cardDao;
    @Autowired
    CarDao carDao;
    @Autowired
    CustomerDao customerDao;
    @Autowired
    OrderTradeRecordDao orderTradeRecordDao;
    @Autowired
    OrderInfoDao orderInfoDao;
    @Autowired
    ParkInfoDao parkInfoDao;

    /**
     * 入场通知
     */
    @Async("threadPoolExecutor")
    public void inParkMessage(String carNumber, String parkName, Long inTime,String requestId){
        //  日志追踪
        MDC.put("requestId", requestId);

        CarDTO carDTO = carDao.getCustCarByCarNumber(carNumber);
        if(carDTO != null){
            try {
                CustomerDTO customerDTO = customerDao.getCustomerById(carDTO.getCustomerId());

                String unionid = customerDTO.getUnionid();
                if(unionid != null){
                    log.info("公众号通知-车辆【{}】入场，客户:【{}】", carNumber, customerDTO.getNickname());
                    //微信公众号发送进场信息
                    InParkMessage message = new InParkMessage();
                    message.setUnionid(customerDTO.getUnionid());
                    message.setCarNumber(carDTO.getCarNumber());
                    message.setParkName(parkName);
                    message.setInTime(DateTimeUtil.stampToString(inTime));
                    String isSuccess = HttpUtil.requestPostBody(inPark, JSONObject.toJSONString(message), null);
                    if (isSuccess != null){
                        log.info("公众号通知-车辆【{}】入场消息发送成功", carNumber);
                    }
                } else {
                    log.info("公众号通知-车辆【{}】入场消息发送失败-客户【{}】未关注公众号", carNumber, customerDTO.getNickname());
                }
            } catch (Exception e) {
                log.error("公众号通知-发送消息失败【{}】", e.getMessage());
            } finally {
            MDC.remove("requestId");
            }
        } else {
            log.error("公众号通知-发送消息失败，用户不存在");
        }
    }

    /**
     * 离场通知
     */
    @Async("threadPoolExecutor")
    public void outParkMessage(OutParkMessage message,String requestId ){
        //  日志追踪
        MDC.put("requestId", requestId);

        try {
            if(message.getUnionid() != null){
                log.info("公众号通知-发送车辆离场场消息，客户:【{}】", message.getNickname());
                //微信公众号发送离场信息
                String jsonStr = JSONObject.toJSONString(message);
                String isSuccess = HttpUtil.requestPostBody(outPark, jsonStr, null);
                if (isSuccess != null){
                    log.info("公众号通知-车辆离场消息发送成功");
                }
            } else {
                log.info("公众号通知-车辆离场消息发送失败-客户【{}】未关注公众号", message.getNickname());
            }
        } catch (Exception e) {
            log.error("公众号通知-发送客户【{}】消息失败【{}】", message.getNickname(), e.getMessage());
        } finally {
            MDC.remove("requestId");
        }
    }

    /**
     * 服务开通通知
     */
    @Async("threadPoolExecutor")
    public void openServiceMessage(OpenServiceMessage message,String requestId){
        //  日志追踪
        MDC.put("requestId", requestId);

        try {
            String unionid = message.getUnionid();
            if(unionid != null){
                log.info("服务开通公众号消息，unionid:【{}】", unionid);
                //微信公众号发送进场信息
                String jsonStr = JSONObject.toJSONString(message);
                String isSuccess = HttpUtil.requestPostBody(openService, jsonStr, null);
                if (isSuccess != null){
                    log.info("服务开通公众号消息发送成功");
                }
            } else {
                log.info("服务开通公众号消息发送-客户【{}】未关注公众号", unionid);
            }
        } catch (Exception e) {
            log.error("发送消息失败【{}】", e.getMessage());
        } finally {
        MDC.remove("requestId");
        }
    }

    /**
     * 公众号离场通知（会员卡信息）
     */
    @Async
    public void monthAndDurationMessage(String orderCode, Long inTime, Long outTime, String money,String requestId){
        //  日志追踪
        MDC.put("requestId", requestId);

        List<OrderTradeRecordDTO> paidOrderTradeRecord = orderTradeRecordDao.getOutPayByOrderCode(orderCode);
        if(paidOrderTradeRecord.size() > 1){
            log.error("订单有{}多次出场支付", orderCode);
        }
        OrderInfoDTO orderInfoDTO = orderInfoDao.getByOrderCode(orderCode);
        //  根据车牌号获取客户车辆
        CarDTO carDTO = carDao.getCustCarByCarNumber(orderInfoDTO.getCarNumber());
        if(carDTO != null){
            //  停车场
            ParkInfo parkInfo = parkInfoDao.selectById(orderInfoDTO.getParkId());
            //  客户
            CustomerDTO customerDTO = customerDao.getCustomerById(carDTO.getCustomerId());
            //  道尔停车场月租车基本信息
            MonthlyCarInfoRes monthlycar =null;
            Integer headStatus = null;
            Integer bodyStatus = null;
            if(parkInfo.getParkSource().equals(3)){
                monthlycar = DaoerApiUtil.getMonthlycar(parkInfo.getBolianParkId(), orderInfoDTO.getCarNumber());
                headStatus = monthlycar.getHead().getStatus();
                bodyStatus = monthlycar.getBody().getStatus();
            }

            OutParkMessage message = new OutParkMessage();
            message.setUnionid(customerDTO.getUnionid());
            message.setNickname(customerDTO.getNickname());
            message.setCarNumber(orderInfoDTO.getCarNumber());
            message.setParkName(parkInfo.getParkName());
            Date inTimeDate = DateTimeUtil.stampToTime(inTime);
            message.setInTime(DateTimeUtil.convertYMDHMS(inTimeDate));
            Date outTimeDate = DateTimeUtil.stampToTime(outTime);
            message.setOutTime(DateTimeUtil.convertYMDHMS(outTimeDate));
            message.setPaidAmount(money);
            message.setCarType("临时车");
            message.setParkDuration(DateTimeUtil.durationTime(outTime - inTime));

            //判断是否是道尔车场月租车
            if(monthlycar !=null && headStatus.equals(1) && (bodyStatus.equals(0) || bodyStatus.equals(2))){
                message.setCarType("月租车");

                String end = monthlycar.getBody().getEndTime();
                Date endTime = DateTimeUtil.fomatDateTime(end);
                int gapCount = DateTimeUtil.getGapCount(new Date(), endTime);
                message.setResidual("月租车" + gapCount + "天");
            } else {
                if(paidOrderTradeRecord.size() > 0 && paidOrderTradeRecord.get(0).getPayType() != null){
                    //月租卡
                    if (paidOrderTradeRecord.get(0).getPayType() == 1){
                        message.setCarType("月租车");

                        //  根据carId和parkId查询客户车辆停车场月租服务
                        CardDTO monthCardDTO = cardDao.getMonthCardByCarIdParkId(carDTO.getId(), parkInfo.getId());
                        int gapCount = DateTimeUtil.getGapCount(new Date(), monthCardDTO.getExpireTime());
                        message.setResidual("月租车" + gapCount + "天");

                        //时长卡
                    } else if (paidOrderTradeRecord.get(0).getPayType() == 2){
                        message.setCarType("时长车");

                        //  根据customerId和parkId查询客户车辆停车场时长服务
                        List<CardDTO> durationCardDTOList = cardDao.getDurationCardByCustomerIdParkId(orderInfoDTO.getCustomerId(), parkInfo.getId());
                        Long duration = 0L;
                        for (CardDTO cardDTO : durationCardDTOList) {
                            duration += cardDTO.getTimeLeft();
                        }
                        message.setResidual("时长车" + duration + "小时");
                    }
                }
            }

            //微信公众号发送离场信息
            outParkMessage(message,requestId);
        }

        MDC.remove("requestId");
    }

    /**
     * 充值成功通知
     */
    @Async("threadPoolExecutor")
    public void rechargeSuccess(RechargeSuccess message,String requestId){

        //  日志追踪
        MDC.put("requestId", requestId);

        try {
            String unionid = message.getUnionid();
            if(unionid != null){
                log.info("公众号通知-发送充值成功通知，客户:【{}】", message.getNickname());
                //微信公众号发送离场信息
                String jsonStr = JSONObject.toJSONString(message);
                String isSuccess = HttpUtil.requestPostBody(rechargeSuccess, jsonStr, null);
                if (isSuccess != null){
                    log.info("公众号通知-充值消息发送成功，客户:【{}】", message.getNickname());
                }
            } else {
                log.info("公众号通知-充值消息发送失败-客户【{}】未关注公众号", message.getNickname());
            }
        } catch (Exception e) {
            log.error("公众号通知-发送客户:【{}】消息失败【{}】", message.getNickname(), e.getMessage());
        } finally {
            MDC.remove("requestId");
        }
    }

}
